# -*- coding: utf-8 -*-

from __future__ import unicode_literals

import pytz
from haystack.generic_views import SearchView
from django.db import transaction
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from django.http import HttpResponse, Http404, HttpResponseRedirect, JsonResponse
from django.shortcuts import render, get_object_or_404, reverse, redirect
from django.core.serializers import serialize
from post.views import _slice_get
from utils import build_comment_tree
from django.views.generic import ListView
from django.views.generic.detail import SingleObjectMixin
from django.utils import timezone
from auser.models import User
from post.models import CommentPraise
from . import categories, areas
from django.utils.decorators import method_decorator
from django.contrib.auth.decorators import login_required
from movie.models import Movie, Comment, Stamp, Review
from datetime import datetime
from django.views.decorators.cache import cache_page
from django.core.cache import cache


# todo: ajax分页
@method_decorator(cache_page(60),name='get')
class MovieIndexView(ListView):
	page_kwarg = 'page'
	paginate_by = 9
	# paginator_class = MoviePaginator
	model = Movie
	# queryset = Comment.objects.all()
	context_object_name = 'movies'
	template_name = 'movie/movie_index.html'

	def get(self, request, *args, **kwargs):
		return super(MovieIndexView, self).get(request, *args, **kwargs)

	def get_context_data(self, **kwargs):
		context = super(MovieIndexView, self).get_context_data(**kwargs)
		# todo: 选择排序方式
		# if self.request.GET.get('sort') == 'comments':
		# 	movies = self.model.objects.annotate(comments=Count('comment')).order_by('-comments')
		# else:
		movies = self.model.objects.all().order_by('rating')
		current_page = int(self.kwargs.get(self.page_kwarg, '1'))
		paginator = Paginator(movies, self.paginate_by)
		try:
			paginator = paginator.page(current_page)  # 获取前端传过来显示当前页的数据 对象
		except PageNotAnInteger:
			# 如果有异常则显示第一页
			paginator = paginator.page(1)
		except EmptyPage:
			# 如果没有得到具体的分页内容的话,则显示最后一页
			paginator = paginator.page(paginator.num_pages)

		context['movies'] = paginator
		context['categories'] = categories
		context['areas'] = areas
		return context


# 条件查询
@cache_page(60)
def search(request):
	maxLength = 9
	if request.method == 'GET':
		# if request.path.endswith('/'):
		# 	return HttpResponseRedirect(reverse('movie:movie_index', args=(1, )))
		if 'key' in request.GET and request.GET['key']:
			key = request.GET.get('key', None)
			movies = Movie.objects.filter(title__contains=key)
			movies = serialize('json', movies)
			return HttpResponse(movies)
		genre = request.GET.get('genre', None)
		area = request.GET.get('area', None)
		year = request.GET.get('year', None)
		M_movies = Movie.objects.all()
		# FIXME: 应该可以重构优化代码
		if year:
			year_begin, year_end = year.split('-')
			to_datetime = lambda strtime: datetime.strptime(strtime, '%Y').replace(tzinfo=pytz.UTC)
			Y_movies = M_movies.filter(year__range=[to_datetime(year_begin), to_datetime(year_end)])
			if genre:
				G_movies = Y_movies.filter(genres__contains=genre)
				if area:
					A_movies = G_movies.filter(countries__contains=area)
					movies = A_movies
				else:
					movies = G_movies
			else:
				if area:
					A_movies = Y_movies.filter(countries__contains=area)
					movies = A_movies
				else:
					movies = Y_movies
		elif genre:
			G_movies = M_movies.filter(genres__contains=genre)
			if area:
				A_movies = G_movies.filter(countries__contains=area)
				movies = A_movies
			else:
				movies = G_movies
		else:
			if area:
				A_movies = M_movies.filter(countries__contains=area)
				movies = A_movies
			else:
				movies = M_movies
		print(type(movies))
		print(len(movies))
		if len(movies) < maxLength:
			maxLength = len(movies)
		movies = movies[:maxLength]
		print(len(movies))
		return HttpResponse(serialize('json', movies))


# TODO: 评论树修改
# 针对单电影->多评论 多影评


# @method_decorator(login_required, name="dispatch")
class MovieDetail(SingleObjectMixin, ListView):
	template_name = "movie/movie_detail.html"

	# 单电影
	def get(self, request, *args, **kwargs):
		self.object = self.get_object(queryset=Movie.objects.all())
		return super(MovieDetail, self).get(request, *args, **kwargs)

	def get_context_data(self, **kwargs):
		context = super(MovieDetail, self).get_context_data(**kwargs)
		context['movie'] = self.object
		context['comments_tree'] = build_comment_tree(self.object)
		# u = Movie.objects.get(pk=6)
		# context['stamp'] =
		return context

	def get_queryset(self):
		pass


class MovieReviews(SingleObjectMixin, ListView):
	template_name = 'movie/most_reviews.html'
	page_kwarg = 'page'
	paginate_by = 3

	def get(self, request, *args, **kwargs):
		self.object = Movie.objects.get(pk=self.kwargs.get('pk', None))
		return super(MovieReviews, self).get(request, *args, **kwargs)

	def get_context_data(self, **kwargs):
		context = super(MovieReviews, self).get_context_data(**kwargs)
		context['movie'] = self.object
		current_page = int(self.kwargs.get(self.page_kwarg, None))
		if not self.get_queryset():
			context['reviews'] = None
			return context
		paginator = Paginator(self.get_queryset(), self.paginate_by)  # 每页三个数据
		try:
			paginator = paginator.page(current_page)  # 获取前端传过来显示当前页的数据 对象
		except PageNotAnInteger:
			# 如果有异常则显示第一页
			paginator = paginator.page(1)
		except EmptyPage:
			print(paginator.num_pages)
			# 如果没有得到具体的分页内容的话,则显示最后一页
			paginator = paginator.page(paginator.num_pages)
		context['reviews'] = paginator
		return context

	def get_queryset(self):
		queryset = self.object.review_set.all()
		return queryset


@login_required(login_url='movie:login')
def commentVerify(request):
	if request.method == "POST":
		movie_id = request.POST.get("movie-id", None)
		user_id = request.POST.get("user-id", None)
		content = request.POST.get("comment-content", None)
		parent_id = request.POST.get("parent-id", None)
		if movie_id and user_id:
			movie = get_object_or_404(Movie, pk=movie_id)
			user = get_object_or_404(User, pk=user_id)
			if parent_id:
				parent_comment = get_object_or_404(Comment, pk=parent_id) if parent_id else None
				comment = Comment.objects.create(movie=movie, user=user,
				                                 movie_name=movie.title, user_username=user.username,
				                                 content=content, timestamp=timezone.now(),
				                                 parent_comment=parent_comment)
				comment.save()
				return HttpResponseRedirect(reverse('movie:movie_detail', args=(movie_id,)))

			# movie_title = Movie.objects.values("title")
			# username = User.objects.values("username")
			comment = Comment.objects.create(movie=movie, user=user,
			                                 movie_name=movie.title, user_username=user.username,
			                                 content=content, timestamp=timezone.now())
			comment.save()
			return JsonResponse({"success": None})
		else:
			return JsonResponse({'fail': "提交失败"})
	else:
		return redirect('/', args=(1,))


@login_required(login_url='movie:login')
def stampVerify(request):
	print('comehere')
	if request.method == "POST":
		rate = request.POST.get('rate', None)
		movie_id = request.POST.get('movie-id', None)
		user_id = request.POST.get('user-id', None)
		mark = request.POST.get('marked', None)
		if movie_id and user_id:
			mark = True if mark else False
			# movie = get_object_or_404(Movie, pk=movie_id)
			# user = get_object_or_404(User, pk=user_id)
			stamp = Stamp.objects.create(movie_id=movie_id,
			                             user_id=user_id,
			                             mark=mark,
			                             rate=float(rate))
			stamp.save()
			return JsonResponse({"rate": stamp.rate})
		else:
			return JsonResponse({'fail': 'fial'})
	else:
		return redirect('/', args=(1,))


@login_required(login_url='movie:login')
def praiseVerify(request):
	if request.method == "POST":
		lid = request.POST.get("praise-id", None)
		cid = request.POST.get("comment-id", None)
		uid = request.POST.get("user-id", None)
		status = request.POST.get("status", None)
		if cid and uid:
			with transaction.atomic():
				cm = get_object_or_404(Comment, pk=cid)
				uu = get_object_or_404(User, pk=uid)
				if status == "1":
					print('status==1')
					CommentPraise.objects.update_or_create(comment_id=cm,
					                                       user_id=uu,
					                                       defaults={"status": False,
					                                                 "timestamp": timezone.now()})
					# F是对字段的引用
					# Comment.objects.filter(pk=cid).update(score=F('score') + 1)
					cm.score -= 1
					cm.save(update_fields=['score'])  # 专门某个字段更新，不然所有字段都会当成参数传过去
				else:
					print('status:', status)
					CommentPraise.objects.update_or_create(comment_id=cm,
					                                       user_id=uu,
					                                       defaults={"status": True,
					                                                 "timestamp": timezone.now()})
					cm.score += 1
					cm.save(update_fields=['score'])
				return JsonResponse({"message": "success"})
		else:
			return JsonResponse({'fail': 'fail'})
	else:
		return redirect('/', args=(1,))


def datatip(request):
	if request.method == "GET":
		q = request.GET.get('q', None)
		if q:
			from api_1.models import MovieSerializer
			from rest_framework.response import Response
			movies = Movie.objects.filter(title__contains=q)
			movies = serialize('json', movies)
			return HttpResponse(movies)
		else:
			return HttpResponse(None)


def full_text_search(request):
	cxt = {}
	if request.method == 'GET':
		q = request.GET.get('q', None)
		print("qq:{q}".format(q=q))
		if q:
			if request.GET.get('to'):
				queryset = Movie.objects.filter(title__contains=q)
				rqueryset = Review.objects.filter(title__contains=q)
				uqueryset = User.objects.filter(username__contains=q)
				cxt['movie'] = queryset
				cxt['review'] = rqueryset
				cxt['user'] = uqueryset
				print(request.GET.get('to'),'------', q)
				return render(request, 'movie/_search_result.html', {'results': cxt})
			q_search(cxt, q)
			print('to', request.GET.get('to'))
			return JsonResponse({'result': cxt})
	return JsonResponse({'result': cxt})


def q_search(cxt, q):
	queryset = Movie.objects.filter(title__contains=q)
	rqueryset = Review.objects.filter(title__contains=q)
	uqueryset = User.objects.filter(username__contains=q)
	queryset, len_one = _slice_get(queryset, section=4, using=False)
	rqueryset, len_two = _slice_get(rqueryset, section=4, using=False)
	uqueryset, len_three = _slice_get(uqueryset, section=4, using=False)
	if len_one > 0:
		cxt['movie'] = {}
		cxt['movie']['data'] = queryset
		cxt['movie']['length'] = len_one
	if len_two > 0:
		cxt['review'] = {}
		cxt['review']['data'] = rqueryset
		cxt['review']['length'] = len_two
	if len_three > 0:
		cxt['user'] = {}
		cxt['user']['data'] = uqueryset
		cxt['user']['length'] = len_three

# def visited_user():
# 	key='visited'
# 	if cache.has_key(key):
# 		data = cache.get(key)
#
# 	return data
